using System;
using System.IO;

namespace SharpObjects.Utils
{
	public class FileWatcher : IDisposable
	{
		public delegate void FileChangedHandler(string sDir, string sFile, System.IO.WatcherChangeTypes ChangeType);

		protected string m_sFilter;
		protected string m_sDir;
		protected FileSystemWatcher m_watcher;

		public event FileChangedHandler FileChanged;

		public FileWatcher(string sFilePath)
		{
			int nInd = sFilePath.LastIndexOf("\\");

			if(nInd == -1)
			{
				m_sDir = Directory.GetCurrentDirectory();
				m_sFilter = sFilePath;
			}
			else
			{
				m_sDir = sFilePath.Substring(0, nInd + 1);
				m_sFilter = sFilePath.Substring(nInd + 1);
			}


			nInd = m_sDir.IndexOf(":");

			if(nInd < 0)
			{
				m_sDir = Directory.GetCurrentDirectory() + "\\" + m_sDir;
			}

			SetWatcher(false);
		}

		public FileWatcher(string sDir, string sFilter, bool bIncludeSubDirectories)
		{
			m_sDir = sDir;
			m_sFilter = sFilter;
			SetWatcher(bIncludeSubDirectories);
		}

		public FileWatcher(string sDir, string sFileName)
		{
			m_sDir = sDir;
			m_sFilter = sFileName.ToLower();
			SetWatcher(false);
		}

		protected void SetWatcher(bool bIncludeSubDirectories)
		{
			m_watcher = new FileSystemWatcher();
			m_watcher.Path = m_sDir;
			m_watcher.IncludeSubdirectories = bIncludeSubDirectories;
			m_watcher.Filter = m_sFilter;

			m_watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;

			m_watcher.Changed += new FileSystemEventHandler(OnChanged);
			m_watcher.Created += new FileSystemEventHandler(OnChanged);
			m_watcher.Deleted += new FileSystemEventHandler(OnChanged);
			m_watcher.Renamed += new RenamedEventHandler(OnRenamed);

			m_watcher.EnableRaisingEvents = true;

		}

		public bool Enabled
		{
			get
			{
				return m_watcher.EnableRaisingEvents;
			}
			set
			{
				m_watcher.EnableRaisingEvents = value;
			}
		}

		private void OnChanged(object source, FileSystemEventArgs e)
		{
			
			if(e.ChangeType == WatcherChangeTypes.Changed || e.ChangeType == WatcherChangeTypes.Created)
			{
				try
				{
					if(FileChanged != null)
					{
						FileChanged(m_sDir, e.Name, e.ChangeType);
					}
				}
				catch{}
			}
		}

		private void OnRenamed(object sender, RenamedEventArgs e)
		{
			try
			{
				if(FileChanged != null)
				{
					FileChanged(m_sDir, e.Name, e.ChangeType);
				}
			}
			catch{}
		}

		//#region IDisposable Members

		public void Dispose()
		{
			this.Enabled = false;
		}

		//#endregion
	}
}
